home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 1997 April / Software of the Month Club 1997 April.iso / pc / dos / games / fastmaze / sqrmaze.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-04  |  70.3 KB  |  1,978 lines

  1. /*
  2.                                FMAZ41 -- Maze Game
  3.  
  4.                               Version 4.1 (10/4/95)
  5.  
  6.  
  7.      Generate and solve mazes on your VGA (or better) display.
  8.  
  9.      The mazes are displayed in three dimensions.
  10.  
  11.      You will be prompted for the number of columns, the tilt, the number of
  12. mazes to be tried before one is selected for display, and a random number seed.
  13.  
  14.      While the maze is being selected, a spinning cursor is displayed.
  15.  
  16.      After the maze is displayed, you may use the Home, PgUp, PgDn, End, up
  17. arrow, and down arrow keys to solve it.  Press "Q" to quit or press "S" to have
  18. the computer solve the maze.
  19.  
  20.      After the maze is solved, you must press some key to continue.
  21.  
  22.      Each maze has exactly one solution that does not involve backtracking
  23. (passing through a doorway more than once).
  24.  
  25.      This program was written by James L. Dean.
  26.  
  27. */
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <math.h>
  31. #include <stdlib.h>
  32. #include <conio.h>
  33. #include <dos.h>
  34. #include <graphics.h>
  35.  
  36. typedef struct corner_record
  37.           {
  38.             int x;
  39.             int y;
  40.           } corner_rec;
  41.  
  42. typedef struct vertex_record
  43.           {
  44.             double x;
  45.             double y;
  46.           } vertex_rec;
  47.  
  48. typedef struct rectangle_record
  49.           {
  50.             vertex_rec vertex [4];
  51.           } rectangle_rec;
  52.  
  53. typedef struct stack_rec_record
  54.           {
  55.             char index_1;
  56.             int  index_2;
  57.           } stack_rec;
  58.  
  59. #define TRUE  1
  60. #define FALSE 0
  61.  
  62. #define GRAPHICS_DRIVER                VGA /* 640x480x16 VGA */
  63. #define GRAPHICS_MODE                VGAHI /* must support red, green, yellow,
  64.                                               and 9 shades of gray */
  65. #define NUM_COLORS                      16
  66. #define TOP_COLOR                       12 /* all but last 3 colors are gray */
  67. #define RIGHT_WALL_COLOR                10
  68. #define FRONT_WALL_COLOR                 7
  69. #define FLOOR_COLOR                      6
  70. #define LEFT_WALL_COLOR                  4
  71. #define BACKOUT_COLOR                   13
  72. #define ADVANCE_COLOR                   14
  73. #define SOLUTION_COLOR                  15
  74. #define WIDTH_OF_GRAPHICS_IN_INCHES      8.0
  75. #define NUM_X_PIXELS                   640
  76. #define WIDTH_OF_GRAPHICS_IN_PIXELS    640
  77. #define HEIGHT_OF_GRAPHICS_IN_INCHES     5.0
  78. #define NUM_Y_PIXELS                   480
  79. #define HEIGHT_OF_GRAPHICS_IN_PIXELS   400
  80.  
  81. #define RELATIVE_WIDTH_OF_WALL           0.2  /* relative to side of square */
  82. #define RELATIVE_HEIGHT_OF_WALL          1.0  /* relative to side of square */
  83. #define MIN_WALL_LENGTH_IN_PIXELS       12
  84.  
  85. static void           display_quadrilateral(double,double,double,double,double,
  86.                        double,double,double,double,double,double,double,double,
  87.                        double,double,double,double,double,double,double,int);
  88. static void           display_solution(int,int,char **,double,double,double,
  89.                        double,double,double,double,double);
  90. static void           draw_line(double,double,double,double,double,double,
  91.                        double,double,double,double,double,double);
  92. static void           free_memory(char ***,char ***,int,stack_rec **);
  93. static void           generate_maze(char **,int,int,stack_rec *,int,int,int *);
  94. static void           get_corner(double,double,double,double,double,double,
  95.                        double,double,double,double,double,corner_rec *);
  96. static void           get_cursor(unsigned char *,unsigned char *,
  97.                        unsigned char *,unsigned char *);
  98. static void           get_defaults(char *,int *,double *,char *,long *);
  99. static void           hash(int *,int *,int *,int *,int *,int *,int *,int *);
  100. static void           increment(int *,int *,int *,int *,int *,int *,int *,
  101.                        int *);
  102. static void           let_user_try_to_solve(int *,int,int,char **,char **,
  103.                        double,double,double,double,double,double,double,double);
  104.        int            main(int,char **);
  105. static int            memory_allocated(char ***,char ***,int,int,stack_rec **,
  106.                        int);
  107.        void interrupt new_critical_error_handler(void);
  108.        void interrupt (*old_critical_error_handler)(void);
  109. static void           output_maze(char **,int,int,double,double,double,double,
  110.                        double,double,double,double);
  111. static void           output_front_top(double,double,double,rectangle_rec *,
  112.                        double,double,double,double,double);
  113. static void           output_left_right(double,double,double,rectangle_rec *,
  114.                        double,double,double,double,double);
  115. static void           put_defaults(char *,int,double,char *,long);
  116. static void           select_maze(char *,char **,int,int,stack_rec *,int,int,
  117.                        int,long);
  118. static void           set_cursor_position(unsigned char,unsigned char);
  119. static void           set_cursor_size(unsigned char,unsigned char);
  120. static void           solve_maze(stack_rec *,char **,int *,int *,int,int);
  121. static void           titillate(void);
  122.  
  123. extern unsigned _stklen=0x8000;
  124.  
  125. static unsigned char cursor_column;
  126. static unsigned char cursor_row;
  127. static unsigned char cursor_start;
  128. static unsigned char cursor_stop;
  129. static int           delta_x [4] [24];
  130. static int           delta_y [4] [24];
  131. static int           file_opened;
  132. static char          titillator [4] = {'|','/','-','\\'};
  133. static int           titillator_index;
  134.  
  135. int main(
  136.   int  argc,
  137.   char *argv[])
  138.     {
  139.       register int                color_num;
  140.       static   char               **computer_page;
  141.       static   double             cos_tilt;
  142.       static   int                default_num_columns;
  143.       static   long               default_num_trials;
  144.       static   char               default_seed [256];
  145.       static   double             default_tilt;
  146.       static   int                delta_index_1a;
  147.       static   int                delta_index_1b;
  148.       static   int                delta_index_1c;
  149.       static   int                delta_index_1d;
  150.       static   int                delta_index_2;
  151.       static   int                ErrorCode;
  152.       static   int                fatal_error;
  153.       static   int                GraphDriver;
  154.       static   int                GraphMode;
  155.       static   char               line [256];
  156.       static   char               *line_ptr;
  157.       static   int                max_num_columns;
  158.       static   int                max_x;
  159.       static   int                max_x_plus_1;
  160.       static   int                max_y;
  161.       static   int                max_y_plus_1;
  162.       static   int                min_num_columns;
  163.       static   int                num_assigned;
  164.       static   int                num_columns;
  165.       static   int                num_rooms_in_maze;
  166.       static   int                num_rows;
  167.       static   long               num_trials;
  168.       static   struct palettetype palette;
  169.       static   double             pixels_per_x;
  170.       static   double             pixels_per_z;
  171.       static   double             radians;
  172.       static   double             radians_per_degree;
  173.       static   double             rel_dist_of_user_from_screen;
  174.       static   int                response;
  175.       static   char               seed [256];
  176.       static   int                seed_index;
  177.       static   double             sin_tilt;
  178.       static   stack_rec          *stack;
  179.       static   double             tilt;
  180.       static   int                tint;
  181.       static   char               **user_page;
  182.       static   int                user_still_interested;
  183.       static   double             x_max;
  184.       static   double             x_offset;
  185.       static   double             y_max;
  186.  
  187.       fatal_error=FALSE;
  188.       delta_x[0][0]=-1;
  189.       delta_y[0][0]=0;
  190.       delta_x[1][0]=0;
  191.       delta_y[1][0]=1;
  192.       delta_x[2][0]=1;
  193.       delta_y[2][0]=0;
  194.       delta_x[3][0]=0;
  195.       delta_y[3][0]=-1;
  196.       delta_index_2=0;
  197.       for (delta_index_1a=0; delta_index_1a < 4; delta_index_1a++)
  198.         for (delta_index_1b=0; delta_index_1b < 4; delta_index_1b++)
  199.           if (delta_index_1a != delta_index_1b)
  200.            for (delta_index_1c=0; delta_index_1c < 4; delta_index_1c++)
  201.              if ((delta_index_1a != delta_index_1c)
  202.              &&  (delta_index_1b != delta_index_1c))
  203.                for (delta_index_1d=0; delta_index_1d < 4; delta_index_1d++)
  204.                   if ((delta_index_1a != delta_index_1d)
  205.                   &&  (delta_index_1b != delta_index_1d)
  206.                   &&  (delta_index_1c != delta_index_1d))
  207.                     {
  208.                       delta_x[delta_index_1a][delta_index_2]
  209.                        =delta_x[0][0];
  210.                       delta_y[delta_index_1a][delta_index_2]
  211.                        =delta_y[0][0];
  212.                       delta_x[delta_index_1b][delta_index_2]
  213.                        =delta_x[1][0];
  214.                       delta_y[delta_index_1b][delta_index_2]
  215.                        =delta_y[1][0];
  216.                       delta_x[delta_index_1c][delta_index_2]
  217.                        =delta_x[2][0];
  218.                       delta_y[delta_index_1c][delta_index_2]
  219.                        =delta_y[2][0];
  220.                       delta_x[delta_index_1d][delta_index_2]
  221.                        =delta_x[3][0];
  222.                       delta_y[delta_index_1d][delta_index_2]
  223.                        =delta_y[3][0];
  224.                       delta_index_2++;
  225.                     };
  226.       min_num_columns=2;
  227.       max_num_columns=(int) (((double) WIDTH_OF_GRAPHICS_IN_PIXELS)/
  228.        ((double) MIN_WALL_LENGTH_IN_PIXELS)-RELATIVE_WIDTH_OF_WALL);
  229.       get_defaults(argv[0],&default_num_columns,&default_tilt,&default_seed[0],
  230.        &default_num_trials);
  231.       do
  232.         {
  233.           clrscr();
  234.           printf(
  235. "                              FMAZ41 -- Maze Game\n\n"
  236. "                             Version 4.1 (10/4/95)\n\n\n"
  237. "     Generate and solve mazes on your VGA (or better) display.\n\n"
  238. "     The mazes are displayed in three dimensions.\n\n"
  239. "     To get the value surrounded by [], just press Enter.\n\n");
  240.           do
  241.             {
  242.               printf("     Number of columns (%d to %d, or 0 to exit) [%d]?  ",
  243.                min_num_columns,max_num_columns,default_num_columns);
  244.               fflush(stdin);
  245.               fgets(&line[0],256,stdin);
  246.               line_ptr=&line[0];
  247.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  248.                 line_ptr++;
  249.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  250.                 num_columns=default_num_columns;
  251.               else
  252.                 {
  253.                   num_assigned=sscanf(line_ptr,"%d",&num_columns);
  254.                   if ((num_assigned == 0) || (num_assigned == EOF))
  255.                     num_columns=-1;
  256.                 }
  257.             }
  258.           while ((num_columns != 0)
  259.           &&     ((num_columns < min_num_columns)
  260.                || (num_columns > max_num_columns)));
  261.           user_still_interested=num_columns;
  262.           if (user_still_interested)
  263.             {
  264.               printf("\n");
  265.               num_rows=(int) (((double) HEIGHT_OF_GRAPHICS_IN_INCHES)
  266.                *((double) num_columns)/((double) WIDTH_OF_GRAPHICS_IN_INCHES));
  267.               if (num_rows < 2)
  268.                 num_rows=2;
  269.               do
  270.                 {
  271.                   printf("     Tilt (30 to 60 degrees) [%lf]?  ",default_tilt);
  272.                   fflush(stdin);
  273.                   fgets(&line[0],256,stdin);
  274.                   line_ptr=&line[0];
  275.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  276.                     line_ptr++;
  277.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  278.                     tilt=default_tilt;
  279.                   else
  280.                     {
  281.                       num_assigned=sscanf(line_ptr,"%lf",&tilt);
  282.                       if ((num_assigned == 0) || (num_assigned == EOF))
  283.                         tilt=(double) 0.0;
  284.                     }
  285.                 }
  286.               while ((tilt < (double) 30.0) || (tilt > (double) 60.0));
  287.               printf("\n");
  288.               do
  289.                 {
  290.                   printf("     Number of trials to allow for maze selection "
  291.                    "[%ld]?  ",default_num_trials);
  292.                   fflush(stdin);
  293.                   fgets(&line[0],256,stdin);
  294.                   line_ptr=&line[0];
  295.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  296.                     line_ptr++;
  297.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  298.                     num_trials=default_num_trials;
  299.                   else
  300.                     {
  301.                       num_assigned=sscanf(line_ptr,"%ld",&num_trials);
  302.                       if ((num_assigned == 0) || (num_assigned == EOF))
  303.                         num_trials=0;
  304.                     }
  305.                 }
  306.               while (num_trials <= 0L);
  307.               printf("\n     Random number seed (8 or fewer digits) [%s]?  ",
  308.                &default_seed[0]);
  309.               fflush(stdin);
  310.               fgets(&line[0],256,stdin);
  311.               line_ptr=&line[0];
  312.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  313.                 line_ptr++;
  314.               if ((*line_ptr != '\n') && (*line_ptr != '\0'))
  315.                 {
  316.                   seed_index=0;
  317.                   while ((seed_index < 8)
  318.                   &&     (*line_ptr)
  319.                   &&     (*line_ptr != '\n'))
  320.                     default_seed[seed_index++]=*(line_ptr++);
  321.                   default_seed[seed_index]='\0';
  322.                 }
  323.               strcpy(&seed[0],&default_seed[0]);
  324.               default_num_columns=num_columns;
  325.               default_tilt=tilt;
  326.               default_num_trials=num_trials;
  327.               max_x=2*num_columns;
  328.               max_x_plus_1=max_x+1;
  329.               max_y=2*num_rows;
  330.               max_y_plus_1=max_y+1;
  331.               num_rooms_in_maze=num_rows*num_columns;
  332.               if (memory_allocated(&computer_page,&user_page,max_x_plus_1,
  333.                max_y_plus_1,&stack,num_rooms_in_maze))
  334.                 {
  335.                   printf(
  336. "\n     While the maze is being selected, a spinning cursor is displayed:  ");
  337.                   select_maze(&seed[0],computer_page,max_x,max_y,stack,
  338.                    num_rooms_in_maze,num_columns,num_rows,num_trials);
  339.                   registerbgidriver(EGAVGA_driver);
  340.                   /*
  341.                      See the Borland documentation on the
  342.                      utilities "BINOBJ" and "TLIB" for
  343.                      information on how to link "EGAVGA.BGI"
  344.                      into a program from "GRAPHICS.LIB".
  345.                   */
  346.                   GraphDriver=GRAPHICS_DRIVER;
  347.                   GraphMode=GRAPHICS_MODE;
  348.                   initgraph(&GraphDriver,&GraphMode,"");
  349.                   ErrorCode=graphresult();
  350.                   if (ErrorCode == 0)
  351.                     {
  352.                       getpalette(&palette);
  353.                       for (color_num=0;
  354.                        color_num < (NUM_COLORS-3);
  355.                        color_num++)
  356.                         { /* evenly spaced shades of gray */
  357.                           tint=(63*color_num)/(NUM_COLORS-3);
  358.                           tint&=0xfc;
  359.                           setrgbpalette(
  360.                            palette.colors[color_num],
  361.                            tint,tint,tint);
  362.                         }
  363.                       setrgbpalette(
  364.                        palette.colors[BACKOUT_COLOR],
  365.                        0xfc,0xfc,0);
  366.                       setrgbpalette(
  367.                        palette.colors[ADVANCE_COLOR],
  368.                        0,0xfc,0);
  369.                       setrgbpalette(
  370.                        palette.colors[SOLUTION_COLOR],
  371.                        0xfc,0,0);
  372.                       settextjustify(CENTER_TEXT,BOTTOM_TEXT);
  373.                       settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
  374.                       setcolor(NUM_COLORS-4);
  375.                       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  376.                        "Arrows - Move    S - Solve    Q - Quit");
  377.                       radians_per_degree=atan(1.0)/45.0;
  378.                       radians=tilt*radians_per_degree;
  379.                       sin_tilt=sin(radians);
  380.                       cos_tilt=cos(radians);
  381.                       x_max=((double) num_columns)+RELATIVE_WIDTH_OF_WALL;
  382.                       pixels_per_x
  383.                        =(((double) WIDTH_OF_GRAPHICS_IN_PIXELS)-1.0)
  384.                        /(x_max*(x_max/(x_max-RELATIVE_HEIGHT_OF_WALL)));
  385.                       x_offset=(x_max/2.0)*(RELATIVE_HEIGHT_OF_WALL
  386.                        /(x_max-RELATIVE_HEIGHT_OF_WALL));
  387.                       y_max=((double) num_rows)+RELATIVE_WIDTH_OF_WALL;
  388.                       pixels_per_z
  389.                        =(((double) HEIGHT_OF_GRAPHICS_IN_PIXELS)-1.0)
  390.                        /sqrt(y_max*y_max
  391.                        +RELATIVE_HEIGHT_OF_WALL*RELATIVE_HEIGHT_OF_WALL);
  392.                       if (y_max > x_max)
  393.                         rel_dist_of_user_from_screen=y_max;
  394.                       else
  395.                         rel_dist_of_user_from_screen=x_max;
  396.                       output_maze(computer_page,max_x,max_y,x_max,x_offset,
  397.                        y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  398.                        rel_dist_of_user_from_screen);
  399.                       let_user_try_to_solve(&response,max_x,max_y,computer_page,
  400.                        user_page,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  401.                        pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  402.                       if ((response == (int) 's')
  403.                       ||  (response == (int) 'S'))
  404.                         {
  405.                           display_solution(max_x,max_y,computer_page,x_max,
  406.                            x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,
  407.                            pixels_per_z,rel_dist_of_user_from_screen);
  408.                           setcolor(NUM_COLORS-4);
  409.                           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  410.                            "Press a key to continue.");
  411.                           response=getch();
  412.                           if (response == 0)
  413.                             response=getch();
  414.                         }
  415.                       closegraph();
  416.                     }
  417.                   else
  418.                     {
  419.                       printf("     Fatal error:  %s\n",
  420.                        grapherrormsg(ErrorCode));
  421.                       fatal_error=TRUE;
  422.                     }
  423.                   free_memory(&computer_page,&user_page,max_y_plus_1,&stack);
  424.                 }
  425.               else
  426.                 {
  427.                   fatal_error=TRUE;
  428.                   printf("     Fatal error:  out of memory.\n");
  429.                 }
  430.             }
  431.         }
  432.       while ((! fatal_error) && (user_still_interested));
  433.       if (! fatal_error)
  434.         put_defaults(argv[0],default_num_columns,default_tilt,
  435.          &default_seed[0],default_num_trials);
  436.       return fatal_error;
  437.     }
  438.  
  439. static void get_defaults(
  440.   char   *argv,
  441.   int    *default_num_columns,
  442.   double *default_tilt,
  443.   char   *default_seed,
  444.   long   *default_num_trials)
  445.     {
  446.       register int  arg_index;
  447.       static   char *arg_ptr;
  448.                FILE *defaults;
  449.       static   char file_name [256];
  450.       static   int  last_period_index;
  451.       static   char line [256];
  452.       static   char *line_ptr;
  453.       static   int  num_assigned;
  454.       static   int  seed_length;
  455.       static   char *seed_ptr;
  456.  
  457.       arg_index=0;
  458.       arg_ptr=argv;
  459.       last_period_index=-1;
  460.       while ((*arg_ptr) && (arg_index < 252))
  461.         {
  462.           if (*arg_ptr == '.')
  463.             last_period_index=arg_index;
  464.           file_name[arg_index++]=*(arg_ptr++);
  465.         }
  466.       if ((*arg_ptr) || (last_period_index < 0))
  467.         {
  468.           *default_num_columns=30;
  469.           *default_tilt=(double) 30.0;
  470.           default_seed[0]='1';
  471.           default_seed[1]='\0';
  472.         }
  473.       else
  474.         {
  475.           file_name[++last_period_index]='I';
  476.           file_name[++last_period_index]='N';
  477.           file_name[++last_period_index]='I';
  478.           file_name[++last_period_index]='\0';
  479.           if ((defaults=fopen(&file_name[0],"r")) == NULL)
  480.             {
  481.               *default_num_columns=30;
  482.               *default_tilt=(double) 30.0;
  483.               default_seed[0]='1';
  484.               default_seed[1]='\0';
  485.               *default_num_trials=5L;
  486.             }
  487.           else
  488.             {
  489.               line_ptr=fgets(&line[0],256,defaults);
  490.               if (line_ptr == NULL)
  491.                 {
  492.                   *default_num_columns=30;
  493.                   *default_tilt=(double) 30.0;
  494.                   default_seed[0]='1';
  495.                   default_seed[1]='\0';
  496.                   *default_num_trials=5L;
  497.                 }
  498.               else
  499.                 {
  500.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  501.                     line_ptr++;
  502.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  503.                     *default_num_columns=30;
  504.                   else
  505.                     {
  506.                       num_assigned=sscanf(line_ptr,"%d",default_num_columns);
  507.                       if ((num_assigned == 0) || (num_assigned == EOF))
  508.                         *default_num_columns=30;
  509.                     }
  510.                   line_ptr=fgets(&line[0],256,defaults);
  511.                   if (line_ptr == NULL)
  512.                     {
  513.                       *default_tilt=(double) 30.0;
  514.                       default_seed[0]='1';
  515.                       default_seed[1]='\0';
  516.                       *default_num_trials=5L;
  517.                     }
  518.                   else
  519.                     {
  520.                       while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  521.                         line_ptr++;
  522.                       if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  523.                         *default_tilt=(double) 30.0;
  524.                       else
  525.                         {
  526.                           num_assigned=sscanf(line_ptr,"%lf",default_tilt);
  527.                           if ((num_assigned == 0) || (num_assigned == EOF))
  528.                             *default_tilt=(double) 30.0;
  529.                         }
  530.                       line_ptr=fgets(&line[0],256,defaults);
  531.                       if (line_ptr == NULL)
  532.                         {
  533.                           default_seed[0]='1';
  534.                           default_seed[1]='\0';
  535.                           *default_num_trials=5L;
  536.                         }
  537.                       else
  538.                         {
  539.                           while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  540.                             line_ptr++;
  541.                           seed_ptr=default_seed;
  542.                           if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  543.                             *(seed_ptr++)='1';
  544.                           else
  545.                             {
  546.                               seed_length=0;
  547.                               while ((seed_length < 8)
  548.                               &&     (*line_ptr)
  549.                               &&     (*line_ptr != '\n')) 
  550.                                 {
  551.                                   *(seed_ptr++)=*(line_ptr++);
  552.                                   seed_length++;
  553.                                 }
  554.                             }
  555.                           *seed_ptr='\0';
  556.                           line_ptr=fgets(&line[0],256,defaults);
  557.                           if (line_ptr == NULL)
  558.                             *default_num_trials=5L;
  559.                           else
  560.                             {
  561.                               while ((*line_ptr == ' ')
  562.                               ||     (*line_ptr == (char) 9))
  563.                                 line_ptr++;
  564.                               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  565.                                 *default_num_trials=5L;
  566.                               else
  567.                                 {
  568.                                   num_assigned
  569.                                    =sscanf(line_ptr,"%ld",default_num_trials);
  570.                                   if ((num_assigned == 0) 
  571.                                   ||  (num_assigned == EOF))
  572.                                     *default_num_trials=5L;
  573.                                 }
  574.                             }
  575.                         }
  576.                     }
  577.                 }
  578.               fclose(defaults);
  579.             }
  580.         }
  581.       return;
  582.     }
  583.  
  584. void interrupt new_critical_error_handler()
  585.     {
  586.       file_opened=FALSE;
  587.       return;
  588.     }
  589.  
  590. static void put_defaults(
  591.   char   *argv,
  592.   int    num_columns,
  593.   double tilt,
  594.   char   *seed,
  595.   long   num_trials)
  596.     {
  597.       static int  arg_index;
  598.       static char *arg_ptr;
  599.              FILE *defaults;
  600.       static char file_name [256];
  601.       static int  last_period_index;
  602.  
  603.       arg_index=0;
  604.       arg_ptr=argv;
  605.       last_period_index=-1;
  606.       while ((*arg_ptr) && (arg_index < 252))
  607.         {
  608.           if (*arg_ptr == '.')
  609.             last_period_index=arg_index;
  610.           file_name[arg_index++]=*(arg_ptr++);
  611.         }
  612.       if ((*arg_ptr == '\0') && (last_period_index >= 0))
  613.         {
  614.           file_name[++last_period_index]='I';
  615.           file_name[++last_period_index]='N';
  616.           file_name[++last_period_index]='I';
  617.           file_name[++last_period_index]='\0';
  618.           old_critical_error_handler=getvect(0x24);
  619.           setvect(0x24,new_critical_error_handler);
  620.           file_opened=TRUE;
  621.           if ((defaults=fopen(&file_name[0],"w")) != NULL)
  622.             {
  623.               setvect(0x24,old_critical_error_handler);
  624.               if (file_opened)
  625.                 {
  626.                   fprintf(defaults,"%d\n%lf\n%s\n%ld\n",num_columns,tilt,seed,
  627.                    num_trials);
  628.                   fclose(defaults);
  629.                 }
  630.             }
  631.           else 
  632.             setvect(0x24,old_critical_error_handler);           
  633.         }
  634.       return;
  635.     }
  636.  
  637. static void get_corner(
  638.   double     x,
  639.   double     y,
  640.   double     z,
  641.   double     pixels_per_x,
  642.   double     pixels_per_z,
  643.   double     cos_tilt,
  644.   double     sin_tilt,
  645.   double     rel_dist_of_user_from_screen,
  646.   double     x_max,
  647.   double     x_offset,
  648.   double     y_max,
  649.   corner_rec *corner)
  650.     {
  651.       double x_adjusted;
  652.       double y_prime;
  653.       double z_adjusted;
  654.       double z_prime;
  655.  
  656.       y_prime=(y_max-y)*cos_tilt-z*sin_tilt;
  657.       z_prime=(y_max-y)*sin_tilt+z*cos_tilt;
  658.       z_adjusted=(y_max/2.0)+rel_dist_of_user_from_screen
  659.        *(z_prime-(y_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
  660.       x_adjusted=(x_max/2.0)+rel_dist_of_user_from_screen
  661.        *(x-(x_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
  662.       x_adjusted+=x_offset;
  663.       corner->x=(int) (pixels_per_x*x_adjusted);
  664.       corner->y
  665.        =(HEIGHT_OF_GRAPHICS_IN_PIXELS-1)-((int) (pixels_per_z*z_adjusted));
  666.       return;
  667.     }
  668.  
  669. static void display_quadrilateral(
  670.   double x_max,
  671.   double x_offset,
  672.   double y_max,
  673.   double x0,
  674.   double y0,
  675.   double z0,
  676.   double x1,
  677.   double y1,
  678.   double z1,
  679.   double x2,
  680.   double y2,
  681.   double z2,
  682.   double x3,
  683.   double y3,
  684.   double z3,
  685.   double pixels_per_x,
  686.   double pixels_per_z,
  687.   double cos_tilt,
  688.   double sin_tilt,
  689.   double rel_dist_of_user_from_screen,
  690.   int    color)
  691.     {
  692.       static corner_rec quadrilateral [4];
  693.  
  694.       get_corner(x0,y0,z0,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  695.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[0]);
  696.       get_corner(x1,y1,z1,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  697.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[1]);
  698.       get_corner(x2,y2,z2,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  699.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[2]);
  700.       get_corner(x3,y3,z3,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  701.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[3]);
  702.       setcolor(color);
  703.       setfillstyle(SOLID_FILL,color);
  704.       fillpoly(4,&(quadrilateral[0].x));
  705.       return;
  706.     }
  707.  
  708. static void output_front_top(
  709.   double        x_max,
  710.   double        x_offset,
  711.   double        y_max,
  712.   rectangle_rec *rectangle,
  713.   double        pixels_per_x,
  714.   double        pixels_per_z,
  715.   double        cos_tilt,
  716.   double        sin_tilt,
  717.   double        rel_dist_of_user_from_screen)
  718.     {
  719.       display_quadrilateral(x_max,x_offset,y_max,
  720.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
  721.        RELATIVE_HEIGHT_OF_WALL,
  722.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
  723.        RELATIVE_HEIGHT_OF_WALL,
  724.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,0.0,
  725.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,0.0,
  726.        pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  727.        rel_dist_of_user_from_screen,FRONT_WALL_COLOR);
  728.       display_quadrilateral(x_max,x_offset,y_max,
  729.        (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,
  730.        RELATIVE_HEIGHT_OF_WALL,
  731.        (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,
  732.        RELATIVE_HEIGHT_OF_WALL,
  733.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
  734.        RELATIVE_HEIGHT_OF_WALL,
  735.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
  736.        RELATIVE_HEIGHT_OF_WALL,
  737.        pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  738.        rel_dist_of_user_from_screen,TOP_COLOR);
  739.       return;
  740.     }
  741.  
  742. static void output_left_right(
  743.   double        x_max,
  744.   double        x_offset,
  745.   double        y_max,
  746.   rectangle_rec *rectangle,
  747.   double        pixels_per_x,
  748.   double        pixels_per_z,
  749.   double        cos_tilt,
  750.   double        sin_tilt,
  751.   double        rel_dist_of_user_from_screen)
  752.     {
  753.       if (2.0*(*rectangle).vertex[0].x > x_max)
  754.         display_quadrilateral(x_max,x_offset,y_max,
  755.          (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,
  756.          RELATIVE_HEIGHT_OF_WALL,
  757.          (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
  758.          RELATIVE_HEIGHT_OF_WALL,
  759.          (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,0.0,
  760.          (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,0.0,
  761.          pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  762.          rel_dist_of_user_from_screen,RIGHT_WALL_COLOR);
  763.       if (2.0*(*rectangle).vertex[1].x < x_max)
  764.         display_quadrilateral(x_max,x_offset,y_max,
  765.          (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
  766.          RELATIVE_HEIGHT_OF_WALL,
  767.          (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,
  768.          RELATIVE_HEIGHT_OF_WALL,
  769.          (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,0.0,
  770.          (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,0.0,
  771.          pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  772.          rel_dist_of_user_from_screen,LEFT_WALL_COLOR);
  773.       return;
  774.     }
  775.  
  776. static void output_maze(
  777.   char   **page,
  778.   int    max_x,
  779.   int    max_y,
  780.   double x_max,
  781.   double x_offset,
  782.   double y_max,
  783.   double cos_tilt,
  784.   double sin_tilt,
  785.   double pixels_per_x,
  786.   double pixels_per_z,
  787.   double rel_dist_of_user_from_screen)
  788.     {
  789.       static   rectangle_rec base_rectangle [4];
  790.       static   int           object_num;
  791.       static   rectangle_rec rectangle [4];
  792.       static   int           vertex_num;
  793.       register int           x;
  794.       register int           y;
  795.       static   double        y_offset;
  796.  
  797.       base_rectangle[0].vertex[0].x=0.0;
  798.       base_rectangle[0].vertex[0].y=0.0;
  799.       base_rectangle[0].vertex[1].x=RELATIVE_WIDTH_OF_WALL;
  800.       base_rectangle[0].vertex[1].y=0.0;
  801.       base_rectangle[0].vertex[2].x=RELATIVE_WIDTH_OF_WALL;
  802.       base_rectangle[0].vertex[2].y=RELATIVE_WIDTH_OF_WALL;
  803.       base_rectangle[0].vertex[3].x=0.0;
  804.       base_rectangle[0].vertex[3].y=RELATIVE_WIDTH_OF_WALL;
  805.       base_rectangle[1].vertex[0].x=RELATIVE_WIDTH_OF_WALL;
  806.       base_rectangle[1].vertex[0].y=0.0;
  807.       base_rectangle[1].vertex[1].x=1.0;
  808.       base_rectangle[1].vertex[1].y=0.0;
  809.       base_rectangle[1].vertex[2].x=1.0;
  810.       base_rectangle[1].vertex[2].y=RELATIVE_WIDTH_OF_WALL;
  811.       base_rectangle[1].vertex[3].x=RELATIVE_WIDTH_OF_WALL;
  812.       base_rectangle[1].vertex[3].y=RELATIVE_WIDTH_OF_WALL;
  813.       base_rectangle[2].vertex[0].x=RELATIVE_WIDTH_OF_WALL;
  814.       base_rectangle[2].vertex[0].y=RELATIVE_WIDTH_OF_WALL;
  815.       base_rectangle[2].vertex[1].x=1.0;
  816.       base_rectangle[2].vertex[1].y=RELATIVE_WIDTH_OF_WALL;
  817.       base_rectangle[2].vertex[2].x=1.0;
  818.       base_rectangle[2].vertex[2].y=1.0;
  819.       base_rectangle[2].vertex[3].x=RELATIVE_WIDTH_OF_WALL;
  820.       base_rectangle[2].vertex[3].y=1.0;
  821.       base_rectangle[3].vertex[0].x=0.0;
  822.       base_rectangle[3].vertex[0].y=RELATIVE_WIDTH_OF_WALL;
  823.       base_rectangle[3].vertex[1].x=RELATIVE_WIDTH_OF_WALL;
  824.       base_rectangle[3].vertex[1].y=RELATIVE_WIDTH_OF_WALL;
  825.       base_rectangle[3].vertex[2].x=RELATIVE_WIDTH_OF_WALL;
  826.       base_rectangle[3].vertex[2].y=1.0;
  827.       base_rectangle[3].vertex[3].x=0.0;
  828.       base_rectangle[3].vertex[3].y=1.0;
  829.       rectangle[0].vertex[0].x=0.0;
  830.       rectangle[0].vertex[0].y=0.0;
  831.       rectangle[0].vertex[1].x=x_max;
  832.       rectangle[0].vertex[1].y=0.0;
  833.       rectangle[0].vertex[2].x=x_max;
  834.       rectangle[0].vertex[2].y=y_max;
  835.       rectangle[0].vertex[3].x=0.0;
  836.       rectangle[0].vertex[3].y=y_max;
  837.       display_quadrilateral(x_max,x_offset,y_max,
  838.        rectangle[object_num].vertex[0].x,rectangle[object_num].vertex[0].y,0.0,
  839.        rectangle[object_num].vertex[1].x,rectangle[object_num].vertex[1].y,0.0,
  840.        rectangle[object_num].vertex[2].x,rectangle[object_num].vertex[2].y,0.0,
  841.        rectangle[object_num].vertex[3].x,rectangle[object_num].vertex[3].y,0.0,
  842.        pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,rel_dist_of_user_from_screen,
  843.        FLOOR_COLOR);
  844.       y_offset=0.0;
  845.       y=0;
  846.       while (y <= max_y)
  847.         {
  848.           for (vertex_num=0; vertex_num < 4; vertex_num++)
  849.             {
  850.               rectangle[0].vertex[vertex_num].x
  851.                =base_rectangle[0].vertex[vertex_num].x;
  852.               rectangle[0].vertex[vertex_num].y
  853.                =base_rectangle[0].vertex[vertex_num].y+y_offset;
  854.             }
  855.           x=0;
  856.           while (x <= max_x)
  857.             {
  858.               if (page[y][x] == 'W')
  859.                 output_left_right(x_max,x_offset,y_max,&rectangle[0],
  860.                  pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  861.                  rel_dist_of_user_from_screen);
  862.               for (vertex_num=0; vertex_num < 4; vertex_num++)
  863.                 (rectangle[0].vertex[vertex_num].x)++;
  864.               x++;
  865.               x++;
  866.             }
  867.           for (vertex_num=0; vertex_num < 4; vertex_num++)
  868.             {
  869.               rectangle[0].vertex[vertex_num].x
  870.                =base_rectangle[0].vertex[vertex_num].x;
  871.               rectangle[0].vertex[vertex_num].y
  872.                =base_rectangle[0].vertex[vertex_num].y+y_offset;
  873.             }
  874.           for (vertex_num=0; vertex_num < 4; vertex_num++)
  875.             {
  876.               rectangle[1].vertex[vertex_num].x
  877.                =base_rectangle[1].vertex[vertex_num].x;
  878.               rectangle[1].vertex[vertex_num].y
  879.                =base_rectangle[1].vertex[vertex_num].y+y_offset;
  880.             }
  881.           x=0;
  882.           while (x <= max_x)
  883.             {
  884.               if (page[y][x] == 'W')
  885.                 output_front_top(x_max,x_offset,y_max,&rectangle[0],
  886.                  pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  887.                  rel_dist_of_user_from_screen);
  888.               for (vertex_num=0; vertex_num < 4; vertex_num++)
  889.                 (rectangle[0].vertex[vertex_num].x)++;
  890.               x++;
  891.               if (x <= max_x)
  892.                 {
  893.                   if (page[y][x] == 'W')
  894.                     output_front_top(x_max,x_offset,y_max,&rectangle[1],
  895.                      pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  896.                      rel_dist_of_user_from_screen);
  897.                   for (vertex_num=0; vertex_num < 4; vertex_num++)
  898.                     (rectangle[1].vertex[vertex_num].x)++;
  899.                   x++;
  900.                 }
  901.             }
  902.           y++;
  903.           if (y <= max_y)
  904.             {
  905.               for (vertex_num=0; vertex_num < 4; vertex_num++)
  906.                 {
  907.                   rectangle[3].vertex[vertex_num].x
  908.                    =base_rectangle[3].vertex[vertex_num].x;
  909.                   rectangle[3].vertex[vertex_num].y
  910.                    =base_rectangle[3].vertex[vertex_num].y+y_offset;
  911.                 }
  912.               x=0;
  913.               while (x <= max_x)
  914.                 {
  915.                   if (page[y][x] == 'W')
  916.                     output_left_right(x_max,x_offset,y_max,&rectangle[3],
  917.                      pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  918.                      rel_dist_of_user_from_screen);
  919.                   for (vertex_num=0; vertex_num < 4; vertex_num++)
  920.                     (rectangle[3].vertex[vertex_num].x)++;
  921.                   x++;
  922.                   x++;
  923.                 }
  924.               for (vertex_num=0; vertex_num < 4; vertex_num++)
  925.                 {
  926.                   rectangle[3].vertex[vertex_num].x
  927.                    =base_rectangle[3].vertex[vertex_num].x;
  928.                   rectangle[3].vertex[vertex_num].y
  929.                    =base_rectangle[3].vertex[vertex_num].y+y_offset;
  930.                 }
  931.               x=0;
  932.               while (x <= max_x)
  933.                 {
  934.                   if (page[y][x] == 'W')
  935.                     output_front_top(x_max,x_offset,y_max,&rectangle[3],
  936.                      pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  937.                      rel_dist_of_user_from_screen);
  938.                   for (vertex_num=0; vertex_num < 4; vertex_num++)
  939.                     (rectangle[3].vertex[vertex_num].x)++;
  940.                   x++;
  941.                   x++;
  942.                 }
  943.               y++;
  944.             }
  945.           y_offset++;
  946.         }
  947.       return;
  948.     }
  949.  
  950. static int memory_allocated(
  951.   char      ***computer_page,
  952.   char      ***user_page,
  953.   int       max_x_plus_1,
  954.   int       max_y_plus_1,
  955.   stack_rec **stack,
  956.   int       num_rooms_in_maze)
  957.     {
  958.       static   int result;
  959.       register int y;
  960.  
  961.       if (((*computer_page)
  962.        =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
  963.         result=FALSE;
  964.       else
  965.         {
  966.           result=TRUE;
  967.           for (y=0; ((result) && (y < max_y_plus_1)); y++)
  968.            result=(((*computer_page)[y]
  969.             =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
  970.           if (! result)
  971.             {
  972.               --y;
  973.               while (y > 0)
  974.                 free((void *) (*computer_page)[--y]);
  975.               free((void *) *computer_page);
  976.             }
  977.         }
  978.       if (result)
  979.         {
  980.           if (((*user_page)
  981.            =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
  982.             {
  983.               result=FALSE;
  984.               for (y=0; y < max_y_plus_1; y++)
  985.                free((void *) (*computer_page)[y]);
  986.               free((void *) *computer_page);
  987.             }
  988.           else
  989.             {
  990.               result=TRUE;
  991.               for (y=0; ((result) && (y < max_y_plus_1)); y++)
  992.                result=(((*user_page)[y]
  993.                 =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
  994.               if (! result)
  995.                 {
  996.                   --y;
  997.                   while (y > 0)
  998.                     free((void *) (*user_page)[--y]);
  999.                   free((void *) *user_page);
  1000.                   for (y=0; y < max_y_plus_1; y++)
  1001.                    free((void *) (*computer_page)[y]);
  1002.                   free((void *) *computer_page);
  1003.                 }
  1004.             }
  1005.         }
  1006.       if (result)
  1007.         {
  1008.           if ((*stack=(stack_rec *) malloc(
  1009.            ((unsigned int) num_rooms_in_maze)*sizeof(stack_rec))) == NULL)
  1010.             {
  1011.               result=FALSE;
  1012.               for (y=0; y < max_y_plus_1; y++)
  1013.                free((void *) (*user_page)[y]);
  1014.               free((void *) *user_page);
  1015.               for (y=0; y < max_y_plus_1; y++)
  1016.                free((void *) (*computer_page)[y]);
  1017.               free((void *) *computer_page);
  1018.             }
  1019.         }
  1020.       return(result);
  1021.     }
  1022.  
  1023. static void free_memory(
  1024.   char      ***computer_page,
  1025.   char      ***user_page,
  1026.   int       max_y_plus_1,
  1027.   stack_rec **stack)
  1028.     {
  1029.       register int y;
  1030.  
  1031.       free((void *) *stack);
  1032.       for (y=0; y < max_y_plus_1; y++)
  1033.         free((void *) (*user_page)[y]);
  1034.       free((void *) *user_page);
  1035.       for (y=0; y < max_y_plus_1; y++)
  1036.         free((void *) (*computer_page)[y]);
  1037.       free((void *) *computer_page);
  1038.       return;
  1039.     }
  1040.  
  1041. static void get_cursor(
  1042.   unsigned char *cursor_row,
  1043.   unsigned char *cursor_column,
  1044.   unsigned char *cursor_start,
  1045.   unsigned char *cursor_stop)
  1046.     {
  1047.       static union REGS in;
  1048.       static union REGS out;
  1049.  
  1050.       in.h.ah=(unsigned char) 3;
  1051.       in.h.bh=(unsigned char) 0;
  1052.       int86(0x10,&in,&out);
  1053.       *cursor_row=out.h.dh;
  1054.       *cursor_column=out.h.dl;
  1055.       *cursor_start=out.h.ch;
  1056.       *cursor_stop=out.h.cl;
  1057.       return;
  1058.     }
  1059.  
  1060. static void set_cursor_position(
  1061.   unsigned char cursor_row,
  1062.   unsigned char cursor_column)
  1063.     {
  1064.       static union REGS in;
  1065.       static union REGS out;
  1066.  
  1067.       in.h.ah=(unsigned char) 2;
  1068.       in.h.dh=cursor_row;
  1069.       in.h.dl=cursor_column;
  1070.       int86(0x10,&in,&out);
  1071.       return;
  1072.     }
  1073.  
  1074. static void set_cursor_size(
  1075.   unsigned char cursor_start,
  1076.   unsigned char cursor_stop)
  1077.     {
  1078.       static union REGS in;
  1079.       static union REGS out;
  1080.  
  1081.       in.h.ah=(unsigned char) 1;
  1082.       in.h.ch=cursor_start;
  1083.       in.h.cl=cursor_stop;
  1084.       int86(0x10,&in,&out);
  1085.       return;
  1086.     }
  1087.  
  1088. static void titillate()
  1089.     {
  1090.       set_cursor_position(cursor_row,cursor_column);
  1091.       titillator_index++;
  1092.       if (titillator_index > 3)
  1093.         titillator_index=0;
  1094.       putchar((int) titillator[titillator_index]);
  1095.       return;
  1096.     }
  1097.  
  1098. static void solve_maze(
  1099.   stack_rec *stack,
  1100.   char      **page,
  1101.   int       *num_rooms_in_solution,
  1102.   int       *adjacency,
  1103.   int       max_x,
  1104.   int       max_y)
  1105.     {
  1106.       int delta_index;
  1107.       int passage_found;
  1108.       int stack_head;
  1109.       int x;
  1110.       int x_next;
  1111.       int y;
  1112.       int y_next;
  1113.  
  1114.       *num_rooms_in_solution=1;
  1115.       *adjacency=0;
  1116.       x=1;
  1117.       y=1;
  1118.       stack_head=-1;
  1119.       page[y][x]='S';
  1120.       do
  1121.         {
  1122.           delta_index=0;
  1123.           passage_found=FALSE;
  1124.           do
  1125.             {
  1126.               while ((delta_index < 4) && (! passage_found))
  1127.                 {
  1128.                   x_next=x+delta_x[delta_index][0];
  1129.                   y_next=y+delta_y[delta_index][0];
  1130.                   if (page[y_next][x_next] == ' ')
  1131.                     passage_found=TRUE;
  1132.                   else
  1133.                     delta_index++;
  1134.                 }
  1135.               if (! passage_found)
  1136.                 {
  1137.                   delta_index=(int) (stack[stack_head].index_1);
  1138.                   page[y][x]=' ';
  1139.                   x-=delta_x[delta_index][0];
  1140.                   y-=delta_y[delta_index][0];
  1141.                   page[y][x]=' ';
  1142.                   x-=delta_x[delta_index][0];
  1143.                   y-=delta_y[delta_index][0];
  1144.                   stack_head--;
  1145.                   delta_index++;
  1146.                 }
  1147.             }
  1148.           while (! passage_found);
  1149.           page[y_next][x_next]='S';
  1150.           x_next+=delta_x[delta_index][0];
  1151.           y_next+=delta_y[delta_index][0];
  1152.           if (y_next <= max_y)
  1153.             {
  1154.               stack_head++;
  1155.               stack[stack_head].index_1=(char) delta_index;
  1156.               page[y_next][x_next]='S';
  1157.               x=x_next;
  1158.               y=y_next;
  1159.             }
  1160.         }
  1161.       while (y_next < max_y);
  1162.       x=max_x-1;
  1163.       y=max_y-1;
  1164.       *adjacency=0;
  1165.       while (stack_head >= 0)
  1166.         {
  1167.           for (delta_index=0; delta_index < 4; delta_index++)
  1168.             {
  1169.               x_next=x+delta_x[delta_index][0];
  1170.               y_next=y+delta_y[delta_index][0];
  1171.               if (page[y_next][x_next] != 'S')
  1172.                 {
  1173.                   if (page[y_next][x_next] == 'W')
  1174.                     {
  1175.                       x_next+=delta_x[delta_index][0];
  1176.                       y_next+=delta_y[delta_index][0];
  1177.                       if (x_next < 0)
  1178.                         (*adjacency)++;
  1179.                       else
  1180.                         if (x_next > max_x)
  1181.                           (*adjacency)++;
  1182.                         else
  1183.                           if (y_next < 0)
  1184.                             (*adjacency)++;
  1185.                           else
  1186.                             if (y_next > max_y)
  1187.                               (*adjacency)++;
  1188.                             else
  1189.                               {
  1190.                                 if (page[y_next][x_next] == 'S')
  1191.                                   (*adjacency)++;
  1192.                               }
  1193.                     }
  1194.                 }
  1195.             }
  1196.           x-=(2*delta_x[stack[stack_head].index_1][0]);
  1197.           y-=(2*delta_y[stack[stack_head].index_1][0]);
  1198.           stack_head--;
  1199.           (*num_rooms_in_solution)++;
  1200.         }
  1201.       for (delta_index=0; delta_index < 4; delta_index++)
  1202.         {
  1203.           x_next=x+delta_x[delta_index][0];
  1204.           y_next=y+delta_y[delta_index][0];
  1205.           if (page[y_next][x_next] != ' ')
  1206.             {
  1207.               if (page[y_next][x_next] == 'W')
  1208.                 {
  1209.                   x_next+=delta_x[delta_index][0];
  1210.                   y_next+=delta_y[delta_index][0];
  1211.                   if (x_next < 0)
  1212.                     (*adjacency)++;
  1213.                   else
  1214.                     if (x_next > max_x)
  1215.                       (*adjacency)++;
  1216.                     else
  1217.                       if (y_next < 0)
  1218.                         (*adjacency)++;
  1219.                       else
  1220.                         if (y_next > max_y)
  1221.                           (*adjacency)++;
  1222.                         else
  1223.                           {
  1224.                             if (page[y_next][x_next] == 'S')
  1225.                               (*adjacency)++;
  1226.                           }
  1227.                 }
  1228.             }
  1229.         }
  1230.       return;
  1231.     }
  1232.  
  1233. static void generate_maze(
  1234.   char      **page,
  1235.   int       max_x,
  1236.   int       max_y,
  1237.   stack_rec *stack,
  1238.   int       num_columns,
  1239.   int       num_rows,
  1240.   int       *seed)
  1241.     {
  1242.       static   int delta_index_1;
  1243.       static   int delta_index_2;
  1244.       static   int digit;
  1245.       static   int digit_num;
  1246.       static   int passage_found;
  1247.       static   int r_n [8];
  1248.       register int r_n_index_1;
  1249.       register int r_n_index_2;
  1250.       static   int search_complete;
  1251.       static   int stack_head;
  1252.       static   int sum;
  1253.       static   int tem_int;
  1254.       static   int x;
  1255.       static   int x_next;
  1256.       static   int y;
  1257.       static   int y_next;
  1258.  
  1259.       r_n[0]=seed[0]+1;
  1260.       r_n[1]=seed[1]+1;
  1261.       r_n[2]=seed[2]+1;
  1262.       r_n[3]=seed[3]+1;
  1263.       r_n[4]=seed[4]+1;
  1264.       r_n[5]=seed[5]+1;
  1265.       r_n[6]=seed[6]+1;
  1266.       r_n[7]=seed[7]+1;
  1267.       for (y=0; y <= max_y; ++y)
  1268.         for (x=0; x <= max_x; ++x)
  1269.           page[y][x]='W';
  1270.       sum=0;
  1271.       for (digit_num=1; digit_num <= 3; ++digit_num)
  1272.         {
  1273.           digit=r_n[0];
  1274.           r_n_index_1=0;
  1275.           for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  1276.             {
  1277.               tem_int=r_n[r_n_index_2];
  1278.               r_n[r_n_index_1]=tem_int;
  1279.               digit+=tem_int;
  1280.               if (digit >= 29)
  1281.                  digit-=29;
  1282.               r_n_index_1=r_n_index_2;
  1283.             }
  1284.           r_n[7]=digit;
  1285.           sum=29*sum+digit;
  1286.         }
  1287.       x=2*(sum % num_columns)+1;
  1288.       sum=0;
  1289.       for (digit_num=1; digit_num <= 3; ++digit_num)
  1290.         {
  1291.           digit=r_n[0];
  1292.           r_n_index_1=0;
  1293.           for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  1294.             {
  1295.               tem_int=r_n[r_n_index_2];
  1296.               r_n[r_n_index_1]=tem_int;
  1297.               digit+=tem_int;
  1298.               if (digit >= 29)
  1299.                  digit-=29;
  1300.               r_n_index_1=r_n_index_2;
  1301.             }
  1302.           r_n[7]=digit;
  1303.           sum=29*sum+digit;
  1304.         }
  1305.       y=2*(sum % num_rows)+1;
  1306.       page[y][x]=' ';
  1307.       stack_head=-1;
  1308.       do
  1309.         {
  1310.           delta_index_1=0;
  1311.           do
  1312.             {
  1313.               delta_index_2=r_n[0];
  1314.               r_n_index_1=0;
  1315.               r_n_index_2=1;
  1316.               while (r_n_index_2 < 8)
  1317.                 {
  1318.                   tem_int=r_n[r_n_index_2];
  1319.                   r_n[r_n_index_1]=tem_int;
  1320.                   delta_index_2+=tem_int;
  1321.                   if (delta_index_2 >= 29)
  1322.                     delta_index_2-=29;
  1323.                   r_n_index_1=r_n_index_2;
  1324.                   r_n_index_2++;
  1325.                 }
  1326.               r_n[7]=delta_index_2;
  1327.             }
  1328.           while (delta_index_2 >= 24);
  1329.           passage_found=FALSE;
  1330.           search_complete=FALSE;
  1331.           while (! search_complete)
  1332.             {
  1333.               while ((delta_index_1 < 4) && (! passage_found))
  1334.                 {
  1335.                   x_next=x+2*delta_x[delta_index_1][delta_index_2];
  1336.                   if (x_next <= 0)
  1337.                     delta_index_1++;
  1338.                   else
  1339.                     if (x_next > max_x)
  1340.                       delta_index_1++;
  1341.                     else
  1342.                       {
  1343.                         y_next=y+2*delta_y[delta_index_1][delta_index_2];
  1344.                         if (y_next <= 0)
  1345.                           delta_index_1++;
  1346.                         else
  1347.                           if (y_next > max_y)
  1348.                             delta_index_1++;
  1349.                           else
  1350.                             if (page[y_next][x_next] == 'W')
  1351.                               passage_found=TRUE;
  1352.                             else
  1353.                               delta_index_1++;
  1354.                       }
  1355.                 }
  1356.               if (! passage_found)
  1357.                 {
  1358.                   if (stack_head >= 0)
  1359.                     {
  1360.                       delta_index_1=(int) (stack[stack_head].index_1);
  1361.                       delta_index_2=stack[stack_head].index_2;
  1362.                       x-=2*delta_x[delta_index_1][delta_index_2];
  1363.                       y-=2*delta_y[delta_index_1][delta_index_2];
  1364.                       stack_head--;
  1365.                       delta_index_1++;
  1366.                     }
  1367.                 }
  1368.               search_complete=((passage_found)
  1369.                || ((stack_head == -1) && (delta_index_1 >= 4)));
  1370.             }
  1371.           if (passage_found)
  1372.             {
  1373.               stack_head++;
  1374.               stack[stack_head].index_1=(char) delta_index_1;
  1375.               stack[stack_head].index_2=delta_index_2;
  1376.               page[y_next][x_next]=' ';
  1377.               page[(y+y_next)/2][(x+x_next)/2]=' ';
  1378.               x=x_next;
  1379.               y=y_next;
  1380.             }
  1381.         }
  1382.       while (stack_head != -1);
  1383.       page[0][1]='S';
  1384.       page[max_y][max_x-1]=' ';
  1385.       return;
  1386.     }
  1387.  
  1388. static void select_maze(
  1389.   char      *seed_ptr,
  1390.   char      **page,
  1391.   int       max_x,
  1392.   int       max_y,
  1393.   stack_rec *stack,
  1394.   int       num_rooms_in_maze,
  1395.   int       num_columns,
  1396.   int       num_rows,
  1397.   long      num_trials)
  1398.     {
  1399.       static   int    adjacency;
  1400.       static   int    counter_0;
  1401.       static   int    counter_1;
  1402.       static   int    counter_2;
  1403.       static   int    counter_3;
  1404.       static   int    counter_4;
  1405.       static   int    counter_5;
  1406.       static   int    counter_6;
  1407.       static   int    counter_7;
  1408.       static   int    min_adjacency;
  1409.       static   int    num_rooms_in_solution;
  1410.       static   int    num_rooms_in_solution_at_min;
  1411.       static   int    r_n [8];
  1412.       register int    r_n_index_1;
  1413.       register int    r_n_index_2;
  1414.       static   int    seed [8];
  1415.       static   int    seed_at_min [8];
  1416.       static   long   trial_num;
  1417.  
  1418.       while ((*seed_ptr == ' ')
  1419.       ||     (*seed_ptr == (char) 9))
  1420.         seed_ptr++;
  1421.       r_n_index_1=0;
  1422.       while ((r_n_index_1 < 8) && (*seed_ptr) && (*seed_ptr != '\n'))
  1423.         r_n[r_n_index_1++]=(int) (*(seed_ptr++) % 10);
  1424.       r_n_index_2=7;
  1425.       while (r_n_index_1 > 0)
  1426.         {
  1427.            r_n_index_1--;
  1428.            r_n[r_n_index_2]=r_n[r_n_index_1];
  1429.            r_n_index_2--;
  1430.         }
  1431.       while (r_n_index_2 >= 0)
  1432.         {
  1433.           r_n[r_n_index_2]=8;
  1434.           r_n_index_2--;
  1435.         }
  1436.       counter_0=r_n[0];
  1437.       counter_1=r_n[1];
  1438.       counter_2=r_n[2];
  1439.       counter_3=r_n[3];
  1440.       counter_4=r_n[4];
  1441.       counter_5=r_n[5];
  1442.       counter_6=r_n[6];
  1443.       counter_7=r_n[7];
  1444.       hash(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,&counter_5,
  1445.        &counter_6,&counter_7);
  1446.       get_cursor(&cursor_row,&cursor_column,&cursor_start,&cursor_stop);
  1447.       set_cursor_size((unsigned char) 32,(unsigned char) 32);
  1448.       titillator_index=0;
  1449.       min_adjacency=2*num_rooms_in_maze+1;
  1450.       num_rooms_in_solution_at_min=0;
  1451.       seed_at_min[0]=counter_0;
  1452.       seed_at_min[1]=counter_1;
  1453.       seed_at_min[2]=counter_2;
  1454.       seed_at_min[3]=counter_3;
  1455.       seed_at_min[4]=counter_4;
  1456.       seed_at_min[5]=counter_5;
  1457.       seed_at_min[6]=counter_6;
  1458.       seed_at_min[7]=counter_7;
  1459.       for (trial_num=num_trials; trial_num > 0L; --trial_num)
  1460.         {
  1461.           titillate();
  1462.           seed[0]=counter_0;
  1463.           seed[1]=counter_1;
  1464.           seed[2]=counter_2;
  1465.           seed[3]=counter_3;
  1466.           seed[4]=counter_4;
  1467.           seed[5]=counter_5;
  1468.           seed[6]=counter_6;
  1469.           seed[7]=counter_7;
  1470.           generate_maze(page,max_x,max_y,stack,num_columns,num_rows,&seed[0]);
  1471.           solve_maze(stack,page,&num_rooms_in_solution,&adjacency,max_x,max_y);
  1472.           if (3*num_rooms_in_solution >= num_rooms_in_maze)
  1473.             {
  1474.               if (adjacency < min_adjacency)
  1475.                 {
  1476.                   min_adjacency=adjacency;
  1477.                   num_rooms_in_solution_at_min=num_rooms_in_solution;
  1478.                   seed_at_min[0]=seed[0];
  1479.                   seed_at_min[1]=seed[1];
  1480.                   seed_at_min[2]=seed[2];
  1481.                   seed_at_min[3]=seed[3];
  1482.                   seed_at_min[4]=seed[4];
  1483.                   seed_at_min[5]=seed[5];
  1484.                   seed_at_min[6]=seed[6];
  1485.                   seed_at_min[7]=seed[7];
  1486.                 }
  1487.               else
  1488.                 {
  1489.                   if (adjacency == min_adjacency)
  1490.                     {
  1491.                       if (num_rooms_in_solution > num_rooms_in_solution_at_min)
  1492.                         {
  1493.                           num_rooms_in_solution_at_min=num_rooms_in_solution;
  1494.                           seed_at_min[0]=seed[0];
  1495.                           seed_at_min[1]=seed[1];
  1496.                           seed_at_min[2]=seed[2];
  1497.                           seed_at_min[3]=seed[3];
  1498.                           seed_at_min[4]=seed[4];
  1499.                           seed_at_min[5]=seed[5];
  1500.                           seed_at_min[6]=seed[6];
  1501.                           seed_at_min[7]=seed[7];
  1502.                         }
  1503.                     }
  1504.                 }
  1505.             }
  1506.           increment(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,
  1507.            &counter_5,&counter_6,&counter_7);
  1508.         }
  1509.       generate_maze(page,max_x,max_y,stack,num_columns,num_rows,
  1510.        &seed_at_min[0]);
  1511.       solve_maze(stack,page,&num_rooms_in_solution,&adjacency,max_x,max_y);
  1512.       return;
  1513.     }
  1514.  
  1515. static int substitution_high [100] =
  1516.              { 4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
  1517.                6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
  1518.                7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
  1519.                3,7,7,1,9,4,0,5,6,6
  1520.              };
  1521. static int substitution_low [100] =
  1522.              { 1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
  1523.                9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
  1524.                3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
  1525.                2,4,5,9,8,2,8,8,3,5
  1526.              };
  1527. static void hash(
  1528.   int *counter_0,
  1529.   int *counter_1,
  1530.   int *counter_2,
  1531.   int *counter_3,
  1532.   int *counter_4,
  1533.   int *counter_5,
  1534.   int *counter_6,
  1535.   int *counter_7)
  1536.     {
  1537.       register int iteration;
  1538.       static   int seed_0;
  1539.       static   int seed_1;
  1540.       static   int seed_2;
  1541.       static   int seed_3;
  1542.       static   int seed_4;
  1543.       static   int seed_5;
  1544.       static   int seed_6;
  1545.       static   int seed_7;
  1546.       register int substitution_index;
  1547.       static   int tem_0;
  1548.       static   int tem_1;
  1549.       static   int tem_2;
  1550.  
  1551.       seed_0=(*counter_0);
  1552.       seed_1=(*counter_1);
  1553.       seed_2=(*counter_2);
  1554.       seed_3=(*counter_3);
  1555.       seed_4=(*counter_4);
  1556.       seed_5=(*counter_5);
  1557.       seed_6=(*counter_6);
  1558.       seed_7=(*counter_7);
  1559.       for (iteration=1; iteration <= 8; iteration++)
  1560.         {
  1561.           substitution_index=10*seed_1+seed_0;
  1562.           tem_0=substitution_low[substitution_index];
  1563.           tem_1=substitution_high[substitution_index];
  1564.           substitution_index=10*seed_3+seed_2;
  1565.           seed_0=substitution_low[substitution_index];
  1566.           tem_2=substitution_high[substitution_index];
  1567.           substitution_index=10*seed_5+seed_4;
  1568.           seed_2=substitution_low[substitution_index];
  1569.           seed_1=substitution_high[substitution_index];
  1570.           substitution_index=10*seed_7+seed_6;
  1571.           seed_5=substitution_low[substitution_index];
  1572.           seed_7=substitution_high[substitution_index];
  1573.           seed_3=tem_0;
  1574.           seed_6=tem_1;
  1575.           seed_4=tem_2;
  1576.         }
  1577.       (*counter_0)=seed_0;
  1578.       (*counter_1)=seed_1;
  1579.       (*counter_2)=seed_2;
  1580.       (*counter_3)=seed_3;
  1581.       (*counter_4)=seed_4;
  1582.       (*counter_5)=seed_5;
  1583.       (*counter_6)=seed_6;
  1584.       (*counter_7)=seed_7;
  1585.       return;
  1586.     }
  1587.  
  1588. static void increment(
  1589.   int *counter_0,
  1590.   int *counter_1,
  1591.   int *counter_2,
  1592.   int *counter_3,
  1593.   int *counter_4,
  1594.   int *counter_5,
  1595.   int *counter_6,
  1596.   int *counter_7)
  1597.     {
  1598.       register tem;
  1599.  
  1600.       tem=(*counter_0)+1;
  1601.       if (tem <= 9)
  1602.         (*counter_0)=tem;
  1603.       else
  1604.         {
  1605.           (*counter_0)=0;
  1606.           tem=(*counter_1)+1;
  1607.           if (tem <= 9)
  1608.             (*counter_1)=tem;
  1609.           else
  1610.             {
  1611.               (*counter_1)=0;
  1612.               tem=(*counter_2)+1;
  1613.               if (tem <= 9)
  1614.                 (*counter_2)=tem;
  1615.               else
  1616.                 {
  1617.                   (*counter_2)=0;
  1618.                   tem=(*counter_3)+1;
  1619.                   if (tem <= 9)
  1620.                     (*counter_3)=tem;
  1621.                   else
  1622.                     {
  1623.                       (*counter_3)=0;
  1624.                       tem=(*counter_4)+1;
  1625.                       if (tem <= 9)
  1626.                         (*counter_4)=tem;
  1627.                       else
  1628.                         {
  1629.                           (*counter_4)=0;
  1630.                           tem=(*counter_5)+1;
  1631.                           if (tem <= 9)
  1632.                             (*counter_5)=tem;
  1633.                           else
  1634.                             {
  1635.                               (*counter_5)=0;
  1636.                               tem=(*counter_6)+1;
  1637.                               if (tem <= 9)
  1638.                                 (*counter_6)=tem;
  1639.                               else
  1640.                                 {
  1641.                                   (*counter_6)=0;
  1642.                                   tem=(*counter_7)+1;
  1643.                                   if (tem <= 9)
  1644.                                     (*counter_7)=tem;
  1645.                                   else
  1646.                                     (*counter_7)=0;
  1647.                                 }
  1648.                             }
  1649.                         }
  1650.                     }
  1651.                 }
  1652.             }
  1653.         }
  1654.       return;
  1655.     }
  1656.  
  1657. static void draw_line(
  1658.   double x1,
  1659.   double y1,
  1660.   double x2,
  1661.   double y2,
  1662.   double x_max,
  1663.   double x_offset,
  1664.   double y_max,
  1665.   double cos_tilt,
  1666.   double sin_tilt,
  1667.   double pixels_per_x,
  1668.   double pixels_per_z,
  1669.   double rel_dist_of_user_from_screen)
  1670.     {
  1671.       static corner_rec end_point [2];
  1672.  
  1673.       get_corner(x1,y1,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
  1674.        cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
  1675.        &end_point[0]);
  1676.       get_corner(x2,y2,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
  1677.        cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
  1678.        &end_point[1]);
  1679.       moveto(end_point[0].x,end_point[0].y);
  1680.       lineto(end_point[1].x,end_point[1].y);
  1681.       return;
  1682.     }
  1683.  
  1684. static void display_solution(
  1685.   int    max_x,
  1686.   int    max_y,
  1687.   char   **page,
  1688.   double x_max,
  1689.   double x_offset,
  1690.   double y_max,
  1691.   double cos_tilt,
  1692.   double sin_tilt,
  1693.   double pixels_per_x,
  1694.   double pixels_per_z,
  1695.   double rel_dist_of_user_from_screen)
  1696.     {
  1697.       static int    delta_index;
  1698.       static int    path_found;
  1699.       static int    x;
  1700.       static int    x_next;
  1701.       static int    x_previous;
  1702.       static double x_relative;
  1703.       static double x_relative_next;
  1704.       static int    y;
  1705.       static int    y_next;
  1706.       static double y_relative;
  1707.       static double y_relative_next;
  1708.       static int    y_previous;
  1709.  
  1710.       setlinestyle(SOLID_LINE,0xffff,THICK_WIDTH);
  1711.       setcolor(SOLUTION_COLOR);
  1712.       x_previous=1;
  1713.       y_previous=-1;
  1714.       x=1;
  1715.       x_relative=(RELATIVE_WIDTH_OF_WALL+1.0)/2.0;
  1716.       y=0;
  1717.       y_relative=RELATIVE_WIDTH_OF_WALL/2.0;
  1718.       do
  1719.         {
  1720.           path_found=FALSE;
  1721.           for (delta_index=0; (! path_found); delta_index++)
  1722.             {
  1723.               x_next=x+delta_x[delta_index][0];
  1724.               y_next=y+delta_y[delta_index][0];
  1725.               if ((x_next != x_previous) || (y_next != y_previous))
  1726.                 if (path_found=(page[y_next][x_next] == 'S'))
  1727.                   {
  1728.                     x_relative_next
  1729.                      =x_relative+((double) delta_x[delta_index][0])/2.0;
  1730.                     y_relative_next
  1731.                      =y_relative+((double) delta_y[delta_index][0])/2.0;
  1732.                   }
  1733.             }
  1734.           draw_line(x_relative,y_relative,x_relative_next,y_relative_next,
  1735.            x_max,x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  1736.            rel_dist_of_user_from_screen);
  1737.           x_relative=x_relative_next;
  1738.           y_relative=y_relative_next;
  1739.           x_previous=x;
  1740.           y_previous=y;
  1741.           x=x_next;
  1742.           y=y_next;
  1743.         }
  1744.       while ((x != max_x-1) || (y != max_y));
  1745.       return;
  1746.     }
  1747.  
  1748. static void let_user_try_to_solve(
  1749.   int    *key_pressed,
  1750.   int    max_x,
  1751.   int    max_y,
  1752.   char   **computer_page,
  1753.   char   **user_page,
  1754.   double x_max,
  1755.   double x_offset,
  1756.   double y_max,
  1757.   double cos_tilt,
  1758.   double sin_tilt,
  1759.   double pixels_per_x,
  1760.   double pixels_per_z,
  1761.   double rel_dist_of_user_from_screen)
  1762.     {
  1763.       static int    delta_index_1;
  1764.       static int    frequency;
  1765.       static int    passage_found;
  1766.       static int    x;
  1767.       static int    x_next;
  1768.       static double x_relative;
  1769.       static double x_relative_next;
  1770.       static int    y;
  1771.       static int    y_next;
  1772.       static double y_relative;
  1773.       static double y_relative_next;
  1774.  
  1775.       setlinestyle(SOLID_LINE,0xffff,NORM_WIDTH);
  1776.       for (y=0; y <= max_y; y++)
  1777.         for (x=0; x <= max_x; x++)
  1778.           if (computer_page[y][x] == 'W')
  1779.             user_page[y][x]='W';
  1780.           else
  1781.             user_page[y][x]=' ';
  1782.       x=1;
  1783.       x_relative=(RELATIVE_WIDTH_OF_WALL+1.0)/2.0;
  1784.       y=1;
  1785.       y_relative=(RELATIVE_WIDTH_OF_WALL+1.0)/2.0;
  1786.       user_page[y][x]='S';
  1787.       setcolor(ADVANCE_COLOR);
  1788.       draw_line(x_relative,RELATIVE_WIDTH_OF_WALL/2.0,x_relative,y_relative,
  1789.        x_max,x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  1790.        rel_dist_of_user_from_screen);
  1791.       do
  1792.         {
  1793.           do
  1794.             {
  1795.               passage_found=TRUE;
  1796.               *key_pressed=getch();
  1797.               if ((*key_pressed != (int) 'Q')
  1798.               &&  (*key_pressed != (int) 'q')
  1799.               &&  (*key_pressed != (int) 'S')
  1800.               &&  (*key_pressed != (int) 's'))
  1801.                 {
  1802.                   if (*key_pressed == 0)
  1803.                     {
  1804.                       *key_pressed=getch();
  1805.                       switch (*key_pressed)
  1806.                         {
  1807.                           case 72:
  1808.                              delta_index_1=3;
  1809.                              break;
  1810.                           case 77:
  1811.                              delta_index_1=2;
  1812.                              break;
  1813.                           case 80:
  1814.                              delta_index_1=1;
  1815.                              break;
  1816.                           case 75:
  1817.                              delta_index_1=0;
  1818.                              break;
  1819.                           default:
  1820.                             {
  1821.                               passage_found=FALSE;
  1822.                               sound(120);
  1823.                               delay(278);
  1824.                               nosound();
  1825.                               *key_pressed=(int) ' ';
  1826.                               break;
  1827.                             }
  1828.                         }
  1829.                     }
  1830.                   else
  1831.                     {
  1832.                       switch (*key_pressed)
  1833.                         {
  1834.                           case 56:
  1835.                             delta_index_1=3;
  1836.                             break;
  1837.                           case 54:
  1838.                             delta_index_1=2;
  1839.                             break;
  1840.                           case 50:
  1841.                             delta_index_1=1;
  1842.                             break;
  1843.                           case 52:
  1844.                             delta_index_1=0;
  1845.                             break;
  1846.                           case 8:
  1847.                             delta_index_1=0;
  1848.                             break;
  1849.                           default:
  1850.                             passage_found=FALSE;
  1851.                             break;
  1852.                         }
  1853.                     }
  1854.                   if (passage_found)
  1855.                     {
  1856.                       x_next=x+delta_x[delta_index_1][0];
  1857.                       if (x_next <= 0)
  1858.                         passage_found=FALSE;
  1859.                       else
  1860.                         if (x_next >= max_x)
  1861.                           passage_found=FALSE;
  1862.                         else
  1863.                           {
  1864.                             y_next=y+delta_y[delta_index_1][0];
  1865.                             if (y_next <= 0)
  1866.                               passage_found=FALSE;
  1867.                             else
  1868.                               if (y_next > max_y)
  1869.                                 passage_found=FALSE;
  1870.                               else
  1871.                                 if (user_page[y_next][x_next] == 'W')
  1872.                                   passage_found=FALSE;
  1873.                           }
  1874.                     }
  1875.                   if (! passage_found)
  1876.                     {
  1877.                       passage_found=FALSE;
  1878.                       sound(120);
  1879.                       delay(278);
  1880.                       nosound();
  1881.                     }
  1882.                 }
  1883.             }
  1884.           while ((! passage_found)
  1885.           &&     (*key_pressed != (int) 'Q')
  1886.           &&     (*key_pressed != (int) 'q')
  1887.           &&     (*key_pressed != (int) 'S')
  1888.           &&     (*key_pressed != (int) 's'));
  1889.           if ((*key_pressed != (int) 'Q')
  1890.           &&  (*key_pressed != (int) 'q')
  1891.           &&  (*key_pressed != (int) 'S')
  1892.           &&  (*key_pressed != (int) 's'))
  1893.             {
  1894.               x_next+=delta_x[delta_index_1][0];
  1895.               x_relative_next=x_relative+((double) (x_next-x))/2.0;
  1896.               y_next+=delta_y[delta_index_1][0];
  1897.               y_relative_next=y_relative+((double) (y_next-y))/2.0;
  1898.               if (y_next < max_y)
  1899.                 {
  1900.                   if (user_page[y_next][x_next] == 'S')
  1901.                     {
  1902.                       setcolor(BACKOUT_COLOR);
  1903.                       user_page[y][x]=' ';
  1904.                     }
  1905.                   else
  1906.                     {
  1907.                       setcolor(ADVANCE_COLOR);
  1908.                       user_page[y_next][x_next]='S';
  1909.                     }
  1910.                   draw_line(x_relative,y_relative,x_relative_next,
  1911.                    y_relative_next,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  1912.                    pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  1913.                 }
  1914.               else
  1915.                 {
  1916.                   setcolor(ADVANCE_COLOR);
  1917.                   draw_line(x_relative,y_relative,x_relative,y_relative+0.5,
  1918.                    x_max,x_offset,y_max,cos_tilt,sin_tilt,
  1919.                    pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  1920.                 }
  1921.               x=x_next;
  1922.               x_relative=x_relative_next;
  1923.               y=y_next;
  1924.               y_relative=y_relative_next;
  1925.             }
  1926.         }
  1927.       while ((y_next < max_y)
  1928.       &&     (*key_pressed != (int) 'Q')
  1929.       &&     (*key_pressed != (int) 'q')
  1930.       &&     (*key_pressed != (int) 'S')
  1931.       &&     (*key_pressed != (int) 's'));
  1932.       setcolor(0);
  1933.       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  1934.        "Arrows - Move    S - Solve    Q - Quit");
  1935.       if    ((*key_pressed != (int) 'Q')
  1936.       &&     (*key_pressed != (int) 'q')
  1937.       &&     (*key_pressed != (int) 'S')
  1938.       &&     (*key_pressed != (int) 's'))
  1939.         {
  1940.           setcolor(NUM_COLORS-4);
  1941.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  1942.           frequency=10;
  1943.           for (delta_index_1=1; delta_index_1 <= 100;
  1944.            delta_index_1++)
  1945.             {
  1946.               sound(frequency);
  1947.               delay(56);
  1948.               nosound();
  1949.               frequency+=10;
  1950.             };
  1951.           setcolor(0);
  1952.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  1953.           setcolor(NUM_COLORS-4);
  1954.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  1955.            "S - Solve    Other - Restart program");
  1956.           while (kbhit())
  1957.             {
  1958.               *key_pressed=getch();
  1959.               if (*key_pressed == 0)
  1960.                 {
  1961.                   *key_pressed=getch();
  1962.                   *key_pressed=(int) ' ';
  1963.                 }
  1964.             }
  1965.           *key_pressed=getch();
  1966.           if (*key_pressed == 0)
  1967.             {
  1968.               *key_pressed=getch();
  1969.               *key_pressed=(int) ' ';
  1970.             }
  1971.           setcolor(0);
  1972.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  1973.            "S - Solve    Other - Restart program");
  1974.         }
  1975.       return;
  1976.     }
  1977. 
  1978.